/**
 * 用户帐号管理,主要功能包括：
 *   1. 用户注册
 *   2. 用户信息变更
 *   3. 用户查询
 * @author lms 2022.07.28
 */
package ms.core.gateway.service;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import ms.core.common.ApiResult;
import ms.core.common.Page;
import ms.core.common.RequestBody;
import ms.core.common.consts.SysErr;
import ms.core.common.utils.UploadedFileUtils;
import ms.core.common.utils.UploadedFileUtils.FileDoc;
import ms.core.gateway.bean.*;
import ms.core.gateway.request.RegUserRequest;
import ms.core.gateway.request.UpdateSelfRequest;
import ms.core.gateway.request.UpdateUserRequest;
import ms.core.gateway.response.SysUserVO;
import ms.core.gateway.request.CreateUserRequest;
import ms.core.gateway.request.QueryUserRequest;
import ms.core.gateway.system.Application;
import ms.core.gateway.tool.SessionTool;
import ms.core.gateway.utils.SysUserUtils;
import ms.core.tool.JsonTool;
import ms.core.tool.StrTool;

public class SysUserService {

	/**
	 * 接口：<div style="color:red"><b> regUsr </b></div><p>
	 * 功能：用户注册(注册用户企业及帐号) <p>
	 * 应用场景：针对有会员的应用系统<p>
	 * 
	 * @param req
	 * @param resp
	 * @param body={RegUserRequest 对象}
	 * @param sid
	 * @return
	 */
	public ApiResult regUser(HttpServletRequest req, HttpServletResponse resp, Map<String, Object> body, String sid) {
		RegUserRequest ru = RegUserRequest.getInstance(body, sid);

		SysUserUtils utils = new SysUserUtils();
		SysUserVO usr = utils.regUser(ru);

		if (Application.userDelegate!=null) Application.userDelegate.afterNewUser(usr);
		formatUser(usr);

		return new ApiResult(true).setData(usr);
	}

	/**
	 * 接口：<div style="color:red"><b> newUsr </b></div><p>
	 * 功能：添加用户,应用场景：<p>
	 *       1.平台或会员管理员添加子账号; <p>
	 *       2.平台管理员添加其他企业帐号;<p>
	 * 
	 * @param req
	 * @param resp
	 * @param body={CreateUserRequest 对象}
	 * @param sid
	 * @return
	 */
	public ApiResult newUser(HttpServletRequest req, HttpServletResponse resp, Map<String, Object> body, String sid) {
		CreateUserRequest newUser = CreateUserRequest.getInstance(body, sid);
		if ( newUser==null || StrTool.isBlank(newUser.getAccount()) || StrTool.isBlank(newUser.getPassword()) )
			return new ApiResult(false, SysErr.SYS_PARAM_ERR);

		SysUserUtils utils = new SysUserUtils();
		utils.newUser(newUser);
		return new ApiResult(true);
	}

	/**
	 * 接口：<div style="color:red"><b> edtSelf </b></div><p>
	 * 功能：修改我的信息 <p>
	 * 
	 * @param req
	 * @param resp
	 * @param body={UpdateUserRequest 对象}
	 * @param sid
	 * @return
	 */
	public ApiResult editSelf(HttpServletRequest req, HttpServletResponse resp, Map<String, Object> body, String sid) {
		UpdateSelfRequest self = UpdateSelfRequest.getInstance(body, sid);

		String uid = SessionTool.getUserUid(sid);
		SysUserUtils utils = new SysUserUtils();
		utils.editSelf(uid, self);
		return new ApiResult(true);
	}

	/**
	 * 接口：<div style="color:red"><b> edtUsr </b></div><p>
	 * 功能：修改人员信息 <p>
	 * 
	 * @param req
	 * @param resp
	 * @param body={UpdateUserRequest 对象}
	 * @param sid
	 * @return
	 */
	public ApiResult editUser(HttpServletRequest req, HttpServletResponse resp, Map<String, Object> body, String sid) {
		UpdateUserRequest edtUser = UpdateUserRequest.getInstance(body, sid);

		String corpUid = null;
		if (!SessionTool.isSuperCorp(sid)) corpUid = SessionTool.getCorpUid(sid);
	
		SysUserUtils utils = new SysUserUtils();
		utils.editUser(corpUid, edtUser);
		return new ApiResult(true);
	}

	/**
	 * 接口：<div style="color:red"><b> uplPortrait </b></div><p>
	 * 功能：上传我的肖像 <p>
	 * 前端传参: 采用 multipart/form-data 表单方式提交参数
	 *     参数: <key,value> 键值对方式
	 * 
	 * @param req
	 * @param resp
	 * @param body={"desc":"肖像描述","files":[{"dst":"上传后磁盘文件(带全路径)","src":"源文件名(无路径)","fieldName":"photo(上传字段)"}]}
	 * @param sid
	 * @return
	 */
	public ApiResult uploadPortrait(HttpServletRequest req, HttpServletResponse resp, Map<String, Object> body, String sid) {
		RequestBody rb = RequestBody.getInstance(body);
		List<FileDoc> files = UploadedFileUtils.toFileDocList("", "desc", "photo", rb);
		if (files==null || files.size()==0) 
			return new ApiResult(false, SysErr.SYS_PARAM_ERR);

		SysUserUtils utils = new SysUserUtils();
		utils.updatePortrait(SessionTool.getUserUid(sid), files);
		return new ApiResult(true);
	}

	/**
	 * 接口：<div style="color:red"><b> sttUsr </b></div><p>
	 * 功能：修改帐户状态 <p>
	 * 
	 * @param req
	 * @param resp
	 * @param body={"uid":用户uid,"state":用户状态}
	 * @param sid
	 * @return
	 */
	public ApiResult setUserState(HttpServletRequest req, HttpServletResponse resp, Map<String, Object> body, String sid) {
		RequestBody rb = RequestBody.getInstance(body);
		String uid = rb.getStrValue("uid", null);
		int state = rb.getIntValue("state", -1);
		if (StrTool.isBlank(uid) || state<SysUserBean.STATE_INACTIVE || state>SysUserBean.STATE_FROZEN)
			return new ApiResult(false, SysErr.SYS_PARAM_ERR);

		String loginUid = SessionTool.getUserUid(sid);
		if (uid.equals(loginUid)) return new ApiResult(false, SysErr.CODE_FAILURE, "不可对自身帐户执行此操作");

		String corpUid = null;
		if (!SessionTool.isSuperCorp(sid)) corpUid = SessionTool.getUserUid(sid);
		
		SysUserUtils utils = new SysUserUtils();
		utils.setUserState(uid, corpUid, state);
		return new ApiResult(true);
	}

	/**
	 * 接口：<div style="color:red"><b> athRole </b></div><p>
	 * 功能：用户授权 <p>
	 * 
	 * @param req
	 * @param resp
	 * @param body={"id":帐号id,"roles":["RoleA","RoleB"]}
	 * @param sid
	 * @return
	 */
	public ApiResult authRole(HttpServletRequest req, HttpServletResponse resp, Map<String, Object> body, String sid) {
		RequestBody rb = RequestBody.getInstance(body);
		long id = rb.getLongValue("id", 0);
		List<String> roles = JsonTool.jsonToListBean(rb.get("roles"), String.class);
		if (id<1 || roles==null || roles.size()==0)
			return new ApiResult(false, SysErr.SYS_PARAM_ERR);

		String corpUid = null;
		if (!SessionTool.isSuperCorp(sid)) corpUid = SessionTool.getCorpUid(sid);

		SysUserUtils utils = new SysUserUtils();
		utils.authRole(corpUid, id, roles);

		return new ApiResult(true);
	}

	/**
	 * 接口：<div style="color:red"><b> setPwd </b></div><p>
	 * 功能：管理员重置指定企业指定帐户密码 <p>
	 * 
	 * @param req
	 * @param resp
	 * @param body={"id":帐号id,"pwd":"密码"}
	 * @param sid
	 * @return
	 */
	public ApiResult setPwd(HttpServletRequest req, HttpServletResponse resp, Map<String, Object> body, String sid) {
		RequestBody rb = RequestBody.getInstance(body);
		long id = rb.getLongValue("id", 0);
		String pwd = rb.getStrValue("pwd", null);
		String corpUid = null;
		//非平台管理员，corpId指定为当前登录帐户的企业id
		if (!SessionTool.isSuperCorp(sid)) corpUid = SessionTool.getCorpUid(sid);

		if (id<1 || StrTool.isBlank(pwd)) 
			return new ApiResult(false, SysErr.SYS_PARAM_ERR, "未指定用户或未设置密码");
		
		SysUserUtils utils = new SysUserUtils();
		utils.setPwd(corpUid, id, pwd);

		return new ApiResult(true);
	}

	/**
	 * 接口：<div style="color:red"><b> altPwd </b></div><p>
	 * 功能：修改我的帐号密码 <p>
	 * 
	 * @param req
	 * @param resp
	 * @param body={"oldPwd":"旧密码","newPwd":"新密码"}
	 * @param sid
	 * @return
	 */
	public ApiResult setMyPwd(HttpServletRequest req, HttpServletResponse resp, Map<String, Object> body, String sid) {
		RequestBody rb = RequestBody.getInstance(body);
		String oldPwd = rb.getStrValue("oldPwd", null);
		String newPwd = rb.getStrValue("newPwd", null);

		if (StrTool.isBlank(oldPwd) || StrTool.isBlank(newPwd)) 
			return new ApiResult(false, SysErr.SYS_PARAM_ERR, "未指定原密码或新密码");

		String uid = SessionTool.getUserUid(sid);
		SysUserUtils utils = new SysUserUtils();
		utils.setMyPwd(uid, oldPwd, newPwd);

		return new ApiResult(true);
	}

	/**
	 * 接口：<div style="color:red"><b> pwdMail </b></div><p>
	 * 功能：发送找回密码邮件 <p>
	 * 
	 * @param req
	 * @param resp
	 * @param body={"uname":"帐户名","code":"验证码"}
	 * @param sid
	 * @return
	 */
	public ApiResult sendPwdMail(HttpServletRequest req, HttpServletResponse resp, Map<String, Object> body, String sid) {
		RequestBody rb = RequestBody.getInstance(body);
		String uname = rb.getStrValue("uname", null);
		String code  = rb.getStrValue("code", null);

		if (StrTool.isBlank(uname) || StrTool.isBlank(code)) 
			return new ApiResult(false, SysErr.SYS_PARAM_ERR, "请输入用户帐号和验证码");

		if (!code.equalsIgnoreCase(SessionTool.getCheckCode(sid))) 
			return new ApiResult(false, SysErr.SYS_CHECKCODE_ERR);

		SysUserUtils utils = new SysUserUtils();
		utils.sendFindPwdMail(uname);
		return new ApiResult(true);
	}

	/**
	 * 接口：<div style="color:red"><b> rstPwd </b></div><p>
	 * 功能：通过重置密码邮件的验证码，重置密码 <p>
	 * 
	 * @param req
	 * @param resp
	 * @param body={"uid":"帐户名","code":"验证码","newPwd":"新密码"}
	 * @param sid
	 * @return
	 */
	public ApiResult resetPwd(HttpServletRequest req, HttpServletResponse resp, Map<String, Object> body, String sid) {
		RequestBody rb = RequestBody.getInstance(body);
		String uid    = rb.getStrValue("uid", null);
		String code   = rb.getStrValue("code", null);
		String newPwd = rb.getStrValue("newPwd", null);

		if (StrTool.isBlank(uid) || StrTool.isBlank(code) || StrTool.isBlank(newPwd)) 
			return new ApiResult(false, SysErr.SYS_PARAM_ERR, "无效请求");

		SysUserUtils utils = new SysUserUtils();
		utils.resetPwdByCode(uid, code, newPwd);

		return new ApiResult(true);
	}

	private void formatUser(SysUserVO usr){
		if (usr==null) return;

		if (Application.userDelegate!=null) 
			Application.userDelegate.formatUser(usr);
	}

	private void formatUser(List<SysUserVO> usrs){
		if (usrs==null || usrs.size()==0)
			return;

		for(int i=0; i<usrs.size(); i++) {
			SysUserVO usr = usrs.get(i);
			formatUser(usr);
		}
	}

	/**
	 * 接口：<div style="color:red"><b> getSelf </b></div><p>
	 * 功能：个人详情 <p>
	 * 
	 * @param req
	 * @param resp
	 * @param body
	 * @param sid
	 * @return
	 */
	public ApiResult getSelf(HttpServletRequest req, HttpServletResponse resp, Map<String, Object> body, String sid) {
		String uid = SessionTool.getUserUid(sid);
		SysUserUtils utils = new SysUserUtils();
		SysUserVO usr = utils.getUser(null, uid);
		formatUser(usr);

		return new ApiResult(true).setData(usr);
	}

	/**
	 * 接口：<div style="color:red"><b> qryUsr </b></div><p>
	 * 功能：用户查询(企业用户，只可查本企业用户) <p>
	 * 
	 * @param req
	 * @param resp
	 * @param body={QueryUserRequest 对象}
	 * @param sid
	 * @return
	 */
	public ApiResult queryUser(HttpServletRequest req, HttpServletResponse resp, Map<String, Object> body, String sid) {
		QueryUserRequest qry = JsonTool.objectToBean(body, QueryUserRequest.class);
		if (!SessionTool.isSuperCorp(sid)) qry.setCorpUid(SessionTool.getCorpUid(sid));

		SysUserUtils utils = new SysUserUtils();
		Page<SysUserVO> pg = utils.queryUser(qry);
		formatUser(pg.getData());

		return new ApiResult(true).setPage(pg);
	}
}
